mod id_card_data;
use id_card_data::ID_CARD_DATA;

fn find(code: &str) -> Option<&str> {
    let code: String = if code.len() == 2 {
        format!("{}0000", code)
    } else if code.len() == 4 {
        format!("{}00", code)
    } else {
        code.to_string()
    };
    ID_CARD_DATA
        .iter()
        .find(|(k, _)| *k == code)
        .map(|(_, v)| *v)
}

fn get_region(region: &str) -> String {
    let province = find(&region[0..2]).unwrap();
    let city = find(&region[0..4]).unwrap_or("市辖区");
    let county = find(region).unwrap();
    format!("{}-{}-{}", province, city, county)
}

fn check(id: &str) -> bool {
    let sum: u32 = id
        .chars()
        .take(17)
        .enumerate()
        .map(|(i, c)| c.to_digit(10).unwrap() * (2u32.pow((17 - i) as u32) % 11))
        .sum();
    let num = (12 - (sum % 11)) % 11;
    if num < 10 {
        id.chars().nth(17).unwrap() == num.to_string().chars().nth(0).unwrap()
    } else {
        id.chars().nth(17).unwrap() == 'X'
    }
}

// 实现一个身份证号码校验算法，用于校验身份证号。输入参数是身份证号，需要判断是否有效、性别、出生日期、输出其籍贯：省-市-区(县)。(下面是举例，号码是随机的)
// 输入：身份证号码
// 输出：身份证号码是否有效、性别、出生日期、籍贯：省-市-区(县)
// 例如：
// 输入：510399200012236015
// 输出：身份证号码错误
// 输入：370683198901117652
// 输出：身份证号码正确,男,1989年01月11日,山东省-烟台市-莱州市
// 输入：31010419900712232X
// 输出：身份证号码正确,女,1990年07月12日,上海市-市辖区-徐汇区
// 370725   88 11 05 149
// 370725 1988 11 05 149 X
pub fn check_id_card(id_card_no: &str) -> String {
    let len = id_card_no.len();
    if len != 18 && len != 15 {
        return "身份证号码错误".to_string();
    }
    if len == 18 && !check(id_card_no) {
        return "身份证号码错误".to_string();
    }

    let region = get_region(&id_card_no[0..6]);
    let year = if len == 18 {
        id_card_no[6..10].to_string()
    } else {
        format!("19{}", &id_card_no[6..8])
    };
    let month = if len == 18 {
        &id_card_no[10..12]
    } else {
        &id_card_no[8..10]
    };
    let day = if len == 18 {
        &id_card_no[12..14]
    } else {
        &id_card_no[10..12]
    };
    let seq = if len == 18 {
        &id_card_no[14..17]
    } else {
        &id_card_no[12..15]
    };

    format!(
        "身份证号码正确,{},{}年{}月{}日,{}",
        if seq.parse::<u32>().unwrap() % 2 == 0 {
            "女"
        } else {
            "男"
        },
        year,
        month,
        day,
        region
    )
}
